// g++ -o parse parse.cc
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
void Test1() {
  istringstream iss;
  ostringstream oss;
  oss << "lei"
      << " shi sb!";          // 可用于拼接字符串
  cout << oss.str() << endl;  // oss缓冲区的所有内容
  iss.str(oss.str());         // 设置iss缓冲区的内容
  cout << iss.str() << endl;

  string str;
  iss >> str;
  cout << str << endl;  // cout遇到空白字符会结束
  iss >> str;
  cout << str << endl;
  iss.clear();  // iss.str("");
}
void init(std::string& m_pattern) {
  // 按顺序存储解析到的pattern项
  // 每个pattern包括一个整数类型和一个字符串，类型为0表示该pattern是常规字符串，为1表示该pattern需要转义
  // 日期格式单独用下面的dataformat存储
  std::vector<std::pair<int, std::string>> patterns;
  // 临时存储常规字符串
  std::string tmp;
  // 日期格式字符串，默认把位于%d后面的大括号对里的全部字符都当作格式字符，不校验格式是否合法
  std::string dateformat;
  // 是否解析出错
  bool error = false;

  // 是否正在解析常规字符，初始时为true
  bool parsing_string = true;
  // 是否正在解析模板字符，%后面的是模板字符
  // bool parsing_pattern = false;

  size_t i = 0;
  while (i < m_pattern.size()) {
    std::string c = std::string(1, m_pattern[i]);
    if (c == "%") {
      if (parsing_string) {
        if (!tmp.empty()) {
          patterns.push_back(std::make_pair(0, tmp));
        }
        tmp.clear();
        parsing_string = false;  // 在解析常规字符时遇到%，表示开始解析模板字符
        // parsing_pattern = true;
        i++;
        continue;
      } else {
        patterns.push_back(std::make_pair(1, c));
        parsing_string = true;  // 在解析模板字符时遇到%，表示这里是一个%转义
        // parsing_pattern = false;
        i++;
        continue;
      }
    } else {                 // not %
      if (parsing_string) {  // 持续解析常规字符直到遇到%，解析出的字符串作为一个常规字符串加入patterns
        tmp += c;
        i++;
        continue;
      } else {  // 模板字符，直接添加到patterns中，添加完成后，状态变为解析常规字符，%d特殊处理
        patterns.push_back(std::make_pair(1, c));
        parsing_string = true;
        // parsing_pattern = false;

        // 后面是对%d的特殊处理，如果%d后面直接跟了一对大括号，那么把大括号里面的内容提取出来作为dateformat
        if (c != "d") {
          i++;
          continue;
        }
        i++;
        if (i < m_pattern.size() && m_pattern[i] != '{') {
          continue;
        }
        i++;
        while (i < m_pattern.size() && m_pattern[i] != '}') {
          dateformat.push_back(m_pattern[i]);
          i++;
        }
        if (m_pattern[i] != '}') {
          // %d后面的大括号没有闭合，直接报错
          std::cout << "[ERROR] LogFormatter::init() "
                    << "pattern: [" << m_pattern << "] '{' not closed"
                    << std::endl;
          error = true;
          break;
        }
        i++;
        continue;
      }
    }
  }  // end while(i < m_pattern.size())

  if (error) {
    cout << "error" << endl;
    return;
  }

  // 模板解析结束之后剩余的常规字符也要算进去
  if (!tmp.empty()) {
    patterns.push_back(std::make_pair(0, tmp));
    tmp.clear();
  }

  // for debug
  std::cout << "patterns:" << std::endl;
  for (auto& v : patterns) {
    std::cout << "type = " << v.first << ", value = " << v.second << std::endl;
  }
  std::cout << "dataformat = " << dateformat << std::endl;
}
void Test2() {
  std::string pattern =
      "%d{%Y-%m-%d %H:%M:%S} [%rms]%T%t%T%N%T%F%T[%p]%T[%c]%T%f:%l%T%m%n";
  // init(pattern);
  string date_fmt;  // 存储时间戳
  // 0 表示常规字符，1 表示模板字符
  std::vector<std::pair<int, std::string>> patterns;
  string tmp;  // 存储常规字符
  bool parse = true;  // true表示即将解析常规字符，false表示即将解析模板字符

  // 有限状态机解析pattern字符串
  for (int i = 0; i < pattern.size(); ++i) {
    string c = string(1, pattern[i]);
    if (c == "%") {
      if (parse) {  // 正在解析常规字符
        if (tmp.size()) patterns.push_back({0, tmp});
        tmp.clear();
        parse = false;  // 在解析常规字符时遇到%，表示开始解析模板字符
        continue;
      } else {  // 正在解析模板字符
        patterns.push_back({1, c});
        parse = true;
        continue;
      }
    } else {        // c != "%"
      if (parse) {  // 正在解析常规字符
        tmp += c;
        continue;
      } else {  // 正在解析模板字符
        patterns.push_back(std::make_pair(1, c));
        parse = true;

        // 对%d的特殊处理
        if (c != "d") {
          continue;
        }
        ++i;
        if (i < pattern.size() && pattern[i] != '{') continue;
        ++i;
        while (i < pattern.size() && pattern[i] != '}')
          date_fmt.push_back(pattern[i++]);
        if (pattern[i] != '}') {
          // %d后面的大括号没有闭合，直接报错
          std::cout << "[ERROR] LogFormatter::init() "
                    << "pattern: [" << pattern << "] '{' not closed"
                    << std::endl;
          break;
        }
      }
    }
  }  // end for
  if (!tmp.empty()) {
    patterns.push_back(std::make_pair(0, tmp));
    tmp.clear();
  }
  // for debug
  std::cout << "patterns:" << std::endl;
  for (auto& v : patterns) {
    std::cout << "type = " << v.first << ", value = " << v.second << std::endl;
  }
  std::cout << "dataformat = " << date_fmt << std::endl;
}
int main() {
  // Test1();
  Test2();

  return 0;
}

// iss.str()
// iss.str("leiyx shi sb!")
// iss >> str , iss缓冲区中内容写到str中
// oss << str , str的内容写到oss缓冲区中